home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / plugin / bezobj / bezier_extrude.cpp next >
Encoding:
C/C++ Source or Header  |  2000-05-21  |  6.9 KB  |  292 lines

  1. #include "..\..\lib\Fly3D.h"
  2. #include "bezobj.h"
  3.  
  4. void bezier_extrude::init()
  5. {
  6.     if (sfmesh) 
  7.         delete sfmesh;
  8.     sfmesh=0;
  9.     if (curve && source)
  10.     {
  11.         pos=curve->pivot;
  12.         build_stripfan();
  13.     }
  14. }
  15.  
  16. bsp_object *bezier_extrude::clone()
  17. {
  18.     bezier_extrude *tmp=new bezier_extrude;
  19.     *tmp=*this;
  20.     tmp->source=this;
  21.     return tmp;
  22. }
  23.  
  24. int bezier_extrude::get_custom_param_desc(int i,param_desc *pd)
  25. {
  26.     if (pd!=0)
  27.     switch(i)
  28.     {
  29.     case 0:
  30.         pd->type='z';
  31.         pd->data=&curve;
  32.         strcpy(pd->name,"curve");
  33.         break;
  34.     case 1:
  35.         pd->type='f';
  36.         pd->data=&width;
  37.         strcpy(pd->name,"width");
  38.         break;
  39.     case 2:
  40.         pd->type='p';
  41.         pd->data=&fanpic;
  42.         strcpy(pd->name,"fanpic");
  43.         break;
  44.     case 3:
  45.         pd->type='p';
  46.         pd->data=&strippic;
  47.         strcpy(pd->name,"strippic");
  48.         break;
  49.     case 4:
  50.         pd->type='f';
  51.         pd->data=&tileu;
  52.         strcpy(pd->name,"tileu");
  53.         break;
  54.     case 5:
  55.         pd->type='f';
  56.         pd->data=&tilev;
  57.         strcpy(pd->name,"tilev");
  58.         break;
  59.     case 6:
  60.         pd->type='f';
  61.         pd->data=&tilew;
  62.         strcpy(pd->name,"tilew");
  63.         break;
  64.     case 7:
  65.         pd->type='i';
  66.         pd->data=&lm[0];
  67.         strcpy(pd->name,"lm1");
  68.         break;
  69.     case 8:
  70.         pd->type='i';
  71.         pd->data=&lm[1];
  72.         strcpy(pd->name,"lm2");
  73.         break;
  74.     case 9:
  75.         pd->type='i';
  76.         pd->data=&lm[2];
  77.         strcpy(pd->name,"lm3");
  78.         break;
  79.     }
  80.     return 10;
  81. }
  82.  
  83. void bezier_extrude::build_stripfan()
  84. {
  85.     if (sfmesh) delete sfmesh;
  86.     sfmesh=new stripfan_mesh;
  87.  
  88.     float *points=new float[MAX_CURVE_VERTS];
  89.     int nv=curve->adaptative_subdiv(flyengine->curveerr,points,MAX_CURVE_VERTS);
  90.  
  91.     sfmesh->add_stripfan(-(nv+1),fanpic,-1);
  92.     sfmesh->add_stripfan(-(nv+1),fanpic,-1);
  93.     sfmesh->add_stripfan(nv*2,strippic,-1);
  94.     
  95.     sfmesh->vertdata[0].pos.vec(0,0,-width);
  96.     sfmesh->vertdata[0].u=sfmesh->vertdata[0].v=0.0f;
  97.     
  98.     int i,j=(nv+1)*2,k=j;
  99.     for( i=1;i<=nv;i++ )
  100.         {
  101.         curve->evaluate(points[i-1],&sfmesh->vertdata[i].pos.x);
  102.         sfmesh->vertdata[j-i]=sfmesh->vertdata[i];
  103.         sfmesh->vertdata[i].pos.z=-width;
  104.         sfmesh->vertdata[j-i].pos.z=width;
  105.         sfmesh->vertdata[j-i].u=sfmesh->vertdata[i].u=sfmesh->vertdata[i].pos.x/tileu;
  106.         sfmesh->vertdata[j-i].v=sfmesh->vertdata[i].v=sfmesh->vertdata[i].pos.y/tilev;
  107.         }
  108.  
  109.     sfmesh->vertdata[i].pos.vec(0,0,width);
  110.     sfmesh->vertdata[i].u=sfmesh->vertdata[i].v=0.0f;
  111.     delete points;
  112.  
  113.     float u=0.0f;
  114.     for( i=0;i<nv;i++ )
  115.     {
  116.     if (i>0)
  117.         u+=(sfmesh->vertdata[i].pos-sfmesh->vertdata[i-1].pos).length();
  118.     
  119.     sfmesh->vertdata[j].pos=sfmesh->vertdata[i+1].pos;
  120.     sfmesh->vertdata[j].u=u/tilew;
  121.     sfmesh->vertdata[j].v=0.0f;
  122.     sfmesh->vertdata[j].ul=(float)i/(nv-1);
  123.     sfmesh->vertdata[j].vl=0.0f;
  124.     j++;
  125.  
  126.     sfmesh->vertdata[j].pos=sfmesh->vertdata[--k].pos;
  127.     sfmesh->vertdata[j].u=sfmesh->vertdata[j-1].u;
  128.     sfmesh->vertdata[j].v=1.0f;
  129.     sfmesh->vertdata[j].ul=sfmesh->vertdata[j-1].ul;
  130.     sfmesh->vertdata[j].vl=1.0f;
  131.     j++;
  132.     }
  133.  
  134.     boundbox bbox;
  135.     bbox.reset();
  136.     for( i=1;i<=nv;i++ )
  137.         bbox.add_point(sfmesh->vertdata[i].pos.x,sfmesh->vertdata[i].pos.y,sfmesh->vertdata[i].pos.z);
  138.     float dx=bbox.max.x-bbox.min.x;
  139.     float dy=bbox.max.y-bbox.min.y;
  140.     int sx,sy,sz;
  141.  
  142.     if (flyengine->appid==FLYAPPID_LIGHTBSP)
  143.     {
  144.         sx=(int)(dx/flyengine->lmpxsize);
  145.         sy=(int)(dy/flyengine->lmpxsize);
  146.         sz=(int)(u/flyengine->lmpxsize);
  147.         if (sx>MAX_CURVE_LMPIXELS)
  148.             sx=MAX_CURVE_LMPIXELS;
  149.         if (sy>MAX_CURVE_LMPIXELS)
  150.             sy=MAX_CURVE_LMPIXELS;
  151.         if (sz>MAX_CURVE_LMPIXELS)
  152.             sz=MAX_CURVE_LMPIXELS;
  153.  
  154.         ((bezier_extrude *)source)->lm[0]=lm[0]=flyengine->add_lightmap(sx,sy);
  155.         ((bezier_extrude *)source)->lm[1]=lm[1]=flyengine->add_lightmap(sx,sy);
  156.         ((bezier_extrude *)source)->lm[2]=lm[2]=flyengine->add_lightmap(sz,1);
  157.         
  158.         memset(flyengine->lm[lm[0]]->bmp,flyengine->amblight,flyengine->lm[lm[0]]->bytesxy);
  159.         memset(flyengine->lm[lm[1]]->bmp,flyengine->amblight,flyengine->lm[lm[1]]->bytesxy);
  160.         memset(flyengine->lm[lm[2]]->bmp,flyengine->amblight,flyengine->lm[lm[2]]->bytesxy);
  161.     }
  162.  
  163.     sfmesh->stripfandata[2]=lm[0];
  164.     sfmesh->stripfandata[5]=lm[1];
  165.     sfmesh->stripfandata[8]=lm[2];
  166.  
  167.     if (lm[0]>0 && lm[0]<flyengine->nlm)
  168.         {
  169.         sx=flyengine->lm[lm[0]]->sizex;
  170.         sy=flyengine->lm[lm[0]]->sizey;
  171.         }
  172.     else sx=sy=1;
  173.  
  174.     j=(nv+1)*2;
  175.     for( i=0;i<j;i++ )
  176.     {
  177.     sfmesh->vertdata[i].ul=(sfmesh->vertdata[i].pos.x-bbox.min.x)/dx;
  178.     sfmesh->vertdata[i].vl=(sfmesh->vertdata[i].pos.y-bbox.min.y)/dy;
  179.     sfmesh->vertdata[i].ul=(sfmesh->vertdata[i].ul*(sx-1)+0.5f)/sx;
  180.     sfmesh->vertdata[i].vl=(sfmesh->vertdata[i].vl*(sy-1)+0.5f)/sy;
  181.     }
  182.  
  183.     if (objmesh) delete objmesh;
  184.     objmesh=sfmesh->build_mesh();
  185.     objmesh->pivotpos=pos;
  186.  
  187.     if (lm[0]>0 && lm[0]<flyengine->nlm)
  188.         flyengine->lm[lm[0]]->set_base(&objmesh->localfaces[0],flyengine->lmpic[flyengine->lm[lm[0]]->pic],pos);
  189.     if (lm[1]>0 && lm[1]<flyengine->nlm)
  190.         flyengine->lm[lm[1]]->set_base(&objmesh->localfaces[nv-1],flyengine->lmpic[flyengine->lm[lm[1]]->pic],pos);
  191. }
  192.  
  193. int bezier_extrude::message(vector& p,float rad,int msg,int param,void *data)
  194. {
  195.     if (msg==FLYOBJM_ILLUM && (flyengine->mapmode&MAPPING_LIGHTMAP))
  196.     {
  197.         light_map *l;
  198.         if (lm[0]>=0 && lm[0]<flyengine->nlm)
  199.             {
  200.             l=flyengine->lm[lm[0]];
  201.             l->illum(p,*((vector *)data),rad,param);
  202.             l->lastupdate=flyengine->cur_step;
  203.             }
  204.         if (lm[1]>=0 && lm[1]<flyengine->nlm)
  205.             {
  206.             l=flyengine->lm[lm[1]];
  207.             l->illum(p,*((vector *)data),rad,param);
  208.             l->lastupdate=flyengine->cur_step;
  209.             }
  210.         if (lm[2]>=0 && lm[2]<flyengine->nlm)
  211.             {
  212.             l=flyengine->lm[lm[2]];
  213.             illuminate_edge(p,rad,*((vector *)data),param);
  214.             l->lastupdate=flyengine->cur_step;
  215.             }
  216.     }
  217.     else 
  218.         if (msg==FLYOBJM_CHANGEPARAM)
  219.             if (param>=0 || 
  220.                 ((param_desc *)data)->data==&flyengine->curveerr)
  221.                 init();
  222.     return 0;
  223. }
  224.  
  225. void bezier_extrude::draw()
  226. {
  227.     if (sfmesh)
  228.     glPushMatrix();
  229.     glTranslatef(pos.x,pos.y,pos.z);
  230.     glMultMatrixf((float *)&mat);
  231.  
  232.     glColor3ub(255,255,255);
  233.     sfmesh->draw(7);
  234.  
  235.     glPopMatrix();
  236. }
  237.  
  238. void bezier_extrude::illuminate_edge(vector& p,float rad,vector& color,int shadows)
  239. {
  240.     int i,k;
  241.     float dist,u;
  242.  
  243.     light_map *l=flyengine->lm[lm[2]];
  244.     unsigned char *uc=l->bmp;
  245.     
  246.     vector center=(p-pos)*mat_t,point,dir;
  247.     rad*=rad;
  248.  
  249.     for( i=0;i<l->sizex;i++ )
  250.     {
  251.         u=(i+0.5f)/l->sizex;
  252.         curve->evaluate(u,&point.x);
  253.         dir=point-center;
  254.         dist=dir.x*dir.x+dir.y*dir.y+dir.z*dir.z;
  255.         if (dist>rad)
  256.             uc+=3;
  257.         else 
  258.             {
  259.             dist=(1.0f-dist/rad)*255.0f;
  260.  
  261.             if (shadows==2)
  262.                 {
  263.                 vector tangent,normal;
  264.                 curve->evaluate_tangent(u,&tangent.x);
  265.                 tangent.normalize();
  266.                 dir.normalize();
  267.                 normal.cross(vector(0,0,1),tangent);
  268.                 float dot=-vec_dot(dir,normal);
  269.                 flyengine->excludecollision=this;
  270.                 if (dot<0.0f ||
  271.                     flyengine->collision_test(flyengine->bsp,center,point))
  272.                     {
  273.                     uc+=3;
  274.                     flyengine->excludecollision=0;
  275.                     continue;
  276.                     }
  277.                 flyengine->excludecollision=0;
  278.                 dist*=dot;
  279.                 }
  280.  
  281.             k=(int)(color.x*dist)+(int)(*uc);
  282.             *(uc++)=k>255?255:k;
  283.  
  284.             k=(int)(color.y*dist)+(int)(*uc);
  285.             *(uc++)=k>255?255:k;
  286.  
  287.             k=(int)(color.z*dist)+(int)(*uc);
  288.             *(uc++)=k>255?255:k;
  289.             }
  290.     }
  291. }
  292.